package com.uniflow.controller;

import com.uniflow.common.PageResult;
import com.uniflow.common.Result;
import com.uniflow.common.ResultCode;
import com.uniflow.entity.Role;
import com.uniflow.service.RoleService;
import com.uniflow.service.RolePermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 角色管理控制器
 */
@RestController
@RequestMapping("/api/v1/roles")
@Validated
public class RoleController {
    
    @Autowired
    private RoleService roleService;
    
    @Autowired
    private RolePermissionService rolePermissionService;
    
    /**
     * 分页查询角色列表
     */
    @GetMapping
    @PreAuthorize("hasAuthority('role:read')")
    public Result<PageResult<Role>> getRoleList(
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize,
            @RequestParam(required = false) String keyword) {
        try {
            PageResult<Role> result = roleService.getRoleList(pageNum, pageSize, keyword);
            return Result.success(result);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 获取所有角色
     */
    @GetMapping("/all")
    @PreAuthorize("hasAuthority('role:read')")
    public Result<List<Role>> getAllRoles() {
        try {
            List<Role> roles = roleService.getAllRoles();
            return Result.success(roles);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 根据ID查询角色详情
     */
    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('role:read')")
    public Result<Role> getRoleById(@PathVariable String id) {
        try {
            Role role = roleService.getRoleById(id);
            if (role == null) {
                return Result.error(ResultCode.ROLE_NOT_FOUND);
            }
            return Result.success(role);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 创建角色
     */
    @PostMapping
    @PreAuthorize("hasAuthority('role:write')")
    public Result<Role> createRole(@Valid @RequestBody CreateRoleRequest request) {
        try {
            Role role = new Role();
            role.setName(request.getName());
            role.setDescription(request.getDescription());
            
            Role createdRole = roleService.createRole(role);
            
            // 处理权限分配
            if (request.getPermissions() != null && !request.getPermissions().trim().isEmpty()) {
                String[] permissionIds = request.getPermissions().split(",");
                List<String> permissionList = new ArrayList<>();
                for (String permissionId : permissionIds) {
                    if (!permissionId.trim().isEmpty()) {
                        permissionList.add(permissionId.trim());
                    }
                }
                if (!permissionList.isEmpty()) {
                    rolePermissionService.updateRolePermissions(createdRole.getId(), permissionList, "system", "system");
                }
            }
            
            return Result.success(createdRole);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 更新角色
     */
    @PutMapping("/{id}")
    @PreAuthorize("hasAuthority('role:write')")
    public Result<Role> updateRole(@PathVariable String id, @Valid @RequestBody UpdateRoleRequest request) {
        try {
            Role role = new Role();
            role.setId(id);
            role.setName(request.getName());
            role.setDescription(request.getDescription());
            
            Role updatedRole = roleService.updateRole(role);
            
            // 处理权限更新
            if (request.getPermissions() != null) {
                if (request.getPermissions().trim().isEmpty()) {
                    // 清空所有权限
                    rolePermissionService.updateRolePermissions(id, new ArrayList<>(), "system", "system");
                } else {
                    String[] permissionIds = request.getPermissions().split(",");
                    List<String> permissionList = new ArrayList<>();
                    for (String permissionId : permissionIds) {
                        if (!permissionId.trim().isEmpty()) {
                            permissionList.add(permissionId.trim());
                        }
                    }
                    rolePermissionService.updateRolePermissions(id, permissionList, "system", "system");
                }
            }
            
            return Result.success(updatedRole);
        } catch (Exception e) {
            return Result.error(ResultCode.UPDATE_FAILED, e.getMessage());
        }
    }
    
    /**
     * 删除角色
     */
    @DeleteMapping("/{id}")
    @PreAuthorize("hasAuthority('role:write')")
    public Result<Void> deleteRole(@PathVariable String id) {
        try {
            // 检查角色是否被用户使用
            if (roleService.isRoleInUse(id)) {
                return Result.error(ResultCode.OPERATION_NOT_ALLOWED, "该角色正在被用户使用，无法删除");
            }
            
            roleService.deleteRole(id);
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.DELETE_FAILED, e.getMessage());
        }
    }
    
    /**
     * 批量删除角色
     */
    @DeleteMapping
    @PreAuthorize("hasAuthority('role:write')")
    public Result<Void> deleteRoles(@RequestBody @NotEmpty List<String> ids) {
        try {
            // 检查每个角色是否被使用
            for (String id : ids) {
                if (roleService.isRoleInUse(id)) {
                    return Result.error(ResultCode.OPERATION_NOT_ALLOWED, "存在角色正在被用户使用，无法删除");
                }
            }
            
            roleService.deleteRoles(ids);
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.DELETE_FAILED, e.getMessage());
        }
    }
    
    /**
     * 根据用户ID查询角色列表
     */
    @GetMapping("/by-user/{userId}")
    @PreAuthorize("hasAuthority('role:read')")
    public Result<List<Role>> getRolesByUserId(@PathVariable String userId) {
        try {
            List<Role> roles = roleService.getRolesByUserId(userId);
            return Result.success(roles);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 为用户分配角色
     */
    @PostMapping("/assign")
    @PreAuthorize("hasAuthority('role:write')")
    public Result<Void> assignRoleToUser(@RequestBody AssignRoleRequest request) {
        try {
            roleService.assignRoleToUser(request.getUserId(), request.getRoleId());
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.UPDATE_FAILED, e.getMessage());
        }
    }
    
    /**
     * 移除用户角色
     */
    @DeleteMapping("/remove")
    @PreAuthorize("hasAuthority('role:write')")
    public Result<Void> removeRoleFromUser(@RequestBody RemoveRoleRequest request) {
        try {
            roleService.removeRoleFromUser(request.getUserId(), request.getRoleId());
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.UPDATE_FAILED, e.getMessage());
        }
    }
    
    /**
     * 批量为用户分配角色
     */
    @PostMapping("/batch-assign")
    @PreAuthorize("hasAuthority('role:write')")
    public Result<Void> batchAssignRolesToUser(@RequestBody BatchAssignRolesRequest request) {
        try {
            roleService.batchAssignRolesToUser(request.getUserId(), request.getRoleIds());
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.UPDATE_FAILED, e.getMessage());
        }
    }
    
    /**
     * 清空用户所有角色
     */
    @DeleteMapping("/clear/{userId}")
    @PreAuthorize("hasAuthority('role:write')")
    public Result<Void> clearUserRoles(@PathVariable String userId) {
        try {
            roleService.clearUserRoles(userId);
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.UPDATE_FAILED, e.getMessage());
        }
    }
    
    /**
     * 检查用户是否拥有指定角色
     */
    @GetMapping("/check-role")
    @PreAuthorize("hasAuthority('role:read')")
    public Result<Boolean> hasRole(@RequestParam String userId, @RequestParam String roleName) {
        try {
            boolean hasRole = roleService.hasRole(userId, roleName);
            return Result.success(hasRole);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 检查用户是否拥有指定权限
     */
    @GetMapping("/check-permission")
    @PreAuthorize("hasAuthority('role:read')")
    public Result<Boolean> hasPermission(@RequestParam String userId, @RequestParam String permission) {
        try {
            boolean hasPermission = roleService.hasPermission(userId, permission);
            return Result.success(hasPermission);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 检查角色名称是否可用
     */
    @GetMapping("/check-name")
    public Result<Boolean> checkRoleName(@RequestParam String name, @RequestParam(required = false) String excludeId) {
        try {
            boolean available = roleService.isNameAvailable(name, excludeId);
            return Result.success(available);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 获取角色统计信息
     */
    @GetMapping("/statistics")
    @PreAuthorize("hasAuthority('role:read')")
    public Result<Map<String, Object>> getRoleStatistics() {
        try {
            Map<String, Object> statistics = roleService.getRoleStatistics();
            return Result.success(statistics);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    // 内部类：请求对象
    
    public static class CreateRoleRequest {
        @NotBlank(message = "角色名称不能为空")
        private String name;
        
        private String description;
        private String permissions;
        
        // getters and setters
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        public String getPermissions() { return permissions; }
        public void setPermissions(String permissions) { this.permissions = permissions; }
    }
    
    public static class UpdateRoleRequest {
        private String name;
        private String description;
        private String permissions;
        
        // getters and setters
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        public String getPermissions() { return permissions; }
        public void setPermissions(String permissions) { this.permissions = permissions; }
    }
    
    public static class AssignRoleRequest {
        @NotBlank(message = "用户ID不能为空")
        private String userId;
        
        @NotBlank(message = "角色ID不能为空")
        private String roleId;
        
        // getters and setters
        public String getUserId() { return userId; }
        public void setUserId(String userId) { this.userId = userId; }
        public String getRoleId() { return roleId; }
        public void setRoleId(String roleId) { this.roleId = roleId; }
    }
    
    public static class RemoveRoleRequest {
        @NotBlank(message = "用户ID不能为空")
        private String userId;
        
        @NotBlank(message = "角色ID不能为空")
        private String roleId;
        
        // getters and setters
        public String getUserId() { return userId; }
        public void setUserId(String userId) { this.userId = userId; }
        public String getRoleId() { return roleId; }
        public void setRoleId(String roleId) { this.roleId = roleId; }
    }
    
    public static class BatchAssignRolesRequest {
        @NotBlank(message = "用户ID不能为空")
        private String userId;
        
        @NotEmpty(message = "角色ID列表不能为空")
        private List<String> roleIds;
        
        // getters and setters
        public String getUserId() { return userId; }
        public void setUserId(String userId) { this.userId = userId; }
        public List<String> getRoleIds() { return roleIds; }
        public void setRoleIds(List<String> roleIds) { this.roleIds = roleIds; }
    }
}